export default async function parseReadableStream(
  readableStream: ReadableStream,
  options: {
    onProgress: (data: any) => void;
  }
) {
  const reader = readableStream
    .pipeThrough(new TextDecoderStream())
    .getReader();
  const parser = new EventStreamTextParser();
  while (true) {
    const { value, done } = await reader.read();
    if (done) {
      return;
    }
    parser.parse(value, options.onProgress);
    // const lines = value.split("\n");
    // lines.forEach((line) => {
    //   if (line !== "") {
    //     options.onProgress(line);
    //   }
    // });
  }
}

async function parseStreamBody(
  stream: ReadableStream<Uint8Array>,
  onProgress: (t: string) => void
) {
  const reader = stream.getReader();
  const decoder = new TextDecoder();
  const parser = new EventStreamTextParser();
  let temp = await reader.read();
  while (!temp.done) {
    const text = decoder.decode(temp.value);
    parser.parse(text, onProgress);
    temp = await reader.read();
  }
  reader.releaseLock();
}

class EventStreamTextParser {
  p = 0;
  result = "";
  escape = false;
  inString = false;
  parse(text: string, onProgress: (t: string) => void) {
    for (let i = 0, len = text.length; i < len; i++) {
      const c = text[i];
      if (c === '"' && !this.escape) {
        this.inString = !this.inString;
      }
      if (c === "{" && !this.escape && !this.inString) {
        this.p += 1;
      }
      if (this.p !== 0) {
        this.result += c;
      }
      if (this.p !== 0 && c === "}" && !this.escape && !this.inString) {
        this.p -= 1;
      }
      if (c === "\\" && !this.escape) {
        this.escape = true;
      } else {
        this.escape = false;
      }
      if (this.p === 0 && this.result !== "") {
        try {
          const parsed = JSON.parse(this.result);
          onProgress(parsed);
        } catch (err) {
          console.error(err);
        }
        this.result = "";
      }
    }
  }
}
